<script setup>
import {
  articleServiceList,
  articleService_addArticle,
  articleService_deleteArticle,
  articleService_getArticleInfo,
  articleService_updateArticle,
  cateService_getList
} from '@/apis/article'
import { baseURL } from '@/utils/config.js'
import { transfromDate } from '@/utils/transformdate'
import { ElMessage, ElMessageBox } from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { computed, nextTick, ref } from 'vue'

import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
// ------- 数据区  -----------
const locale = zhCn
let loading = ref(true)
let dialogTitle = ref('')
let title = ref('文章管理')
let total = ref(0)
// 控制预览抽屉组件
let previewVisable = ref(false)

// 绑定组件实例
let ruleFormRef = ref(null)
let editorRef = ref(null)

const status_options = ref([
  {
    value: '已发布',
    label: '已发布'
  },
  {
    value: '草稿',
    label: '草稿'
  }
])

// 下拉框
// 给下拉框绑定的状态
// let status_id = ref('')
let cate_options = ref([])

// 抽屉组件
let drawer = ref(false)
const direction = ref('rtl')

let tableData = ref([])

// 计算属性，处理日期
const articleDate = computed(() => {
  return transfromDate(articleForm.value.pub_date)
})

// 获取文章列表所需参数
const params = ref({
  pagenum: 1,
  pagesize: 10,
  cate_id: '',
  state: ''
})
// 定义验证规则
const myRule = ref({
  // aa
  title: [
    {
      required: true,
      message: '请输入标题',
      trigger: 'blur'
    }
  ],
  cate: [
    {
      required: true,
      message: '请选择分类',
      trigger: 'blur'
    }
  ],
  img_cover: [
    {
      required: true,
      trigger: 'blur'
    }
  ],
  content: [
    {
      required: true,
      message: '请输入文章内容',
      trigger: 'blur'
    }
  ]
})

// 用于添加的表单
const articleForm = ref({
  title: '',
  cate_id: '',
  content: null,
  cover_img: '',
  state: ''
})

let imageUrl = ref('')
// ---------- 方法区 -------------

// 1. 发送获取文章分类列表
let initData = async () => {
  // 获取文章分类
  let { data } = await cateService_getList()
  // 映射为option
  cate_options.value = data.map((item) => ({
    value: item.id,
    label: item.cate_name
  }))

  getArticleList()
  loading.value = false
}

let getArticleList = async () => {
  console.log(params.value)
  // 2. 【下拉框】获取文章列表，映射为所有文章状态
  const res = await articleServiceList(params.value)
  loading.value = false
  total.value = res.total
  tableData.value = res.data
  tableData.value.forEach((item) => {
    item.pub_date = transfromDate(item.pub_date)
  })
}

// 3. 点击发布或者草稿，封装FormData，发送到后端
const add_Update_Article = async () => {
  const fd = new FormData()
  for (let key in articleForm.value) {
    fd.append(key, articleForm.value[key])
  }
  // 有id就是修改，修改的话，就调用更新接口
  if (articleForm.value.id) {
    // await articleService_updateArticle(articleForm.value)

    console.log(articleForm.value.cover_img)
    await articleService_updateArticle(fd)
  } else {
    console.log(fd)
    // await articleService_addArticle(new FormData(ruleFormRef))
    await articleService_addArticle(fd)
    // 添加最新的文章，定位到最后一页，我们通过改变当前页码来控制
    total.value = total.value + 1
    params.value.pagenum = Number(
      Math.ceil(total.value / params.value.pagesize)
    )
    console.log(params.value.pagenum)
  }
  ElMessage({
    type: 'success',
    message: '发布成功'
  })
  drawer.value = false
  getArticleList()
}

function draft() {
  articleForm.value.state = '草稿'
  add_Update_Article()
}
function submit() {
  articleForm.value.state = '已发布'
  ElMessageBox.confirm('你确定发布此文章吗', {
    confirmButtonText: '确认',
    cancelButtonText: '取消'
  })
    .then(() => {
      add_Update_Article()
    })
    .catch(() => {
      // catch error
    })
}

const handleAvatarSuccess = (response, uploadFile) => {
  imageUrl.value = URL.createObjectURL(uploadFile.raw)
  // File对象，form里面存转换好的file对象，但是在渲染的时候，渲染的是imageUrl，也就是转换为url的对象
  // const file = new File([imageUrl.value], uploadFile.name)
  console.log(uploadFile.raw)
  articleForm.value.cover_img = uploadFile.raw
}

// 添加之前重置表单
const handleDrawer = () => {
  dialogTitle.value = '添加文章'
  drawer.value = true
  nextTick(() => {
    resetForm()
  })
}

// 5. 重置表单【添加之前都要重置表单】
const resetForm = () => {
  editorRef.value.setHTML('')
  Object.keys(articleForm.value).forEach((key) => (articleForm.value[key] = ''))
  imageUrl.value = ''
}

// 2. 点击编辑按钮，回显数据，由于预览和编辑的回显都是调用同一个接口，
// 所以我们只需要加上一个标识去判断即可
/**
 * @param {*} row 遍历的每一项
 * @param {*} flag 标识，true表示编辑，false表示预览
 */
const handleEdit = async (row, flag) => {
  if (flag) {
    dialogTitle.value = '编辑文章'
    drawer.value = true
  } else {
    previewVisable.value = true
  }
  loading.value = true

  console.log(row)
  const allowedFileTypes = ['image/png', 'image/jpeg', 'image/gif']
  const { data } = await articleService_getArticleInfo(row.id)
  articleForm.value = data
  // 拼接前缀  "http://127.0.0.1:5173/62f9a9ea-4426-4d2d-94dd-d7be6fa2680c"
  imageUrl.value = baseURL + articleForm.value.cover_img
  const fileName = articleForm.value.cover_img.replace('/uploads/', '')
  fetch(imageUrl)
    .then((res) => res.blob())
    .then((blob) => {
      // console.log(blob)
      // 回显的时候，cover_img要存放转换好的file对象，也就是当前的url去转换后的对象
      articleForm.value.cover_img = new File([blob], fileName, {
        type: allowedFileTypes
      })
      console.log(articleForm.value.cover_img)
    })

    .catch((err) => {
      console.log(err)
    })
  // res = res.body.blob()

  // 设置富文本内容
  if (!editorRef.value) {
    loading.value = false
    return
  }
  editorRef.value.setHTML(articleForm.value.content)
  loading.value = false
}

const handleDelete = async (row) => {
  ElMessageBox.confirm('你确定删除此文章吗')
    .then(async () => {
      await articleService_deleteArticle(row.id)
      ElMessage({
        type: 'success',
        message: '删除成功'
      })
      getArticleList()
    })
    .catch(() => {
      // catch error
    })
}

// 方法：点击搜索，按照条件进行筛选
const search = async () => {
  params.value.cate_id = articleForm.value.cate_id
  params.value.state = articleForm.value.state
  getArticleList()
}

const renew = () => {
  articleForm.value.cate_id = ''
  articleForm.value.state = ''
  params.value.cate_id = articleForm.value.cate_id
  params.value.state = articleForm.value.state
  params.value.pagenum = 1
  params.value.pagesize = 10
  getArticleList()
}

// 7. 分页-handleSizeChange, page-size 改变时触发
const handleSizeChange = (perPage) => {
  // console.log('per' + perPage)
  // 改变每一页的时候，需要改变每页显示的页面
  params.value.pagesize = perPage
  getArticleList()
}
// current-page改变时触发
const handleCurrentChange = (currentPage) => {
  // console.log(currentPage)
  // 当前页改变的时候，需要改变传给后端的当前页
  params.value.pagenum = currentPage
  getArticleList()
}

initData()
</script>

<template>
  <CardPage :title="title">
    <el-button class="button" type="primary" @click="handleDrawer"
      >发布文章</el-button
    >
    <template #extra>
      文章分类：
      <el-select
        v-model="articleForm.cate_id"
        class="m-2"
        placeholder="请选择"
        size="large"
      >
        <el-option
          v-for="item in cate_options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      发布状态：
      <el-select
        v-model="articleForm.state"
        class="m-2"
        placeholder="请选择"
        size="large"
      >
        <el-option
          v-for="item in status_options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>

      <el-button type="primary" @click="search()">搜索</el-button>
      <el-button type="default" @click="renew()">重置</el-button>

      <el-table
        class="list"
        :data="tableData"
        :row-height="40"
        :width="700"
        :height="400"
        :footer-height="50"
      >
        <el-table-column label="文章标题" prop="title">
          <template #default="scope">
            <div style="display: flex; align-items: center">
              <el-link
                type="primary"
                style="margin-left: 10px"
                :underline="false"
                @click="handleEdit(scope.row, false)"
                >{{ scope.row.title }}</el-link
              >
            </div>
          </template>
        </el-table-column>

        <el-table-column label="分类" prop="cate_name" />
        <el-table-column label="发表时间" prop="pub_date" />
        <el-table-column label="状态" prop="state" />

        <el-table-column height="100" label="操作">
          <template #default="scope">
            <el-icon
              color="#3f96f1"
              :size="18"
              @click="handleEdit(scope.row, true)"
              class="icon_class edit_icon"
            >
              <Edit />
            </el-icon>
            <el-icon
              color="#f67d7d"
              :size="18"
              @click="handleDelete(scope.row)"
              class="icon_class del_icon"
            >
              <Delete />
            </el-icon>
          </template>
        </el-table-column>
        <template #empty>
          <div
            class="flex items-center justify-center h-100%"
            style="justify-content: center"
          >
            <el-empty />
          </div>
        </template>
      </el-table>

      <!-- 页脚分页 - 国际化 -->
      <el-config-provider :locale="locale">
        <el-pagination
          class="footer_page"
          background
          v-model:current-page="params.pagenum"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          :page-sizes="[10, 5, 3, 2]"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </el-config-provider>

      <!-- 抽屉组件 -->
      <el-drawer v-model="drawer" :direction="direction" size="50%">
        <template #header>
          <p>{{ dialogTitle }}</p>
        </template>
        <template #default>
          <!-- 表单 -->
          <el-form
            ref="ruleFormRef"
            :model="articleForm"
            :rules="myRule"
            label-width="120px"
            class="demo-ruleForm"
            status-icon
          >
            <el-form-item label="文章标题" prop="title">
              <el-input
                v-model="articleForm.title"
                size="large"
                placeholder="请输入标题"
              />
            </el-form-item>

            <el-form-item label="文章分类" prop="cate">
              <el-select
                v-model="articleForm.cate_id"
                class="m-2"
                placeholder="请选择"
                size="large"
              >
                <el-option
                  v-for="item in cate_options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="文章封面" prop="img_cover">
              <el-upload
                class="avatar-uploader"
                action="https://fe-bigevent-web.itheima.net/da3dd87e-7eb4-42a4-a9c4-ecf96d44cf94"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
              >
                <img v-if="imageUrl" :src="imageUrl" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
                <!-- <div class="avatar-uploader">请选择头像</div> -->
              </el-upload>
            </el-form-item>

            <el-form-item
              label="文章内容"
              class="editor_content"
              prop="content"
            >
              <QuillEditor
                v-model:content="articleForm.content"
                contentType="html"
                theme="snow"
                ref="editorRef"
                class="editor"
              />
              <!-- 富文本 -->
            </el-form-item>
          </el-form>
        </template>
        <template #footer>
          <div style="flex: auto">
            <el-button type="primary" @click="submit">发布</el-button>
            <el-button type="primary" @click="draft">草稿</el-button>
          </div>
        </template>
      </el-drawer>

      <!-- 预览- 抽屉组件 -->
      <el-drawer v-model="previewVisable" :direction="direction" size="50%">
        <template #header>
          <p>文章预览</p>
        </template>

        <template #default>
          <div>
            <h4>{{ articleForm.title }}</h4>
            <div>
              <span>发布时间：{{ articleDate }} &nbsp;</span>
              <span>文章分类：{{ articleForm.cate_name }}</span>
            </div>
            <hr />
            <div>
              <img :src="imageUrl" alt="" />
            </div>
            <div class="content" v-html="articleForm.content"></div>
          </div>
        </template>
      </el-drawer>
    </template>
  </CardPage>
</template>

<style lang="scss" scoped>
.m-2 {
  margin-right: 40px;
}

.list {
  margin-top: 20px;
}

.footer_page {
  float: right;
  padding: 20px;
}

:deep .el-table tr {
  height: 60px;
}

// 封面
// :deep .el-upload {
//   width: 230px;
//   height: 215px;
// }
.avatar-uploader img {
  width: 100%;
  height: 100%;
}
.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.avatar-uploader-icon {
  line-height: 178px;
  height: 178px;
  width: 178px;
  font-size: 16px;
  color: #8c939d;
  text-align: center;
}

.editor_content :deep .el-form-item__content {
  flex-direction: column;
  flex: none;
  height: 300px;

  .ql-toolbar.ql-snow {
    width: 590px;
  }

  .editor {
    flex: 1;
    width: 100%;
    height: 300px;
  }
}
</style>
